package com.flmes.base.util;

import lombok.experimental.UtilityClass;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * @Author: flmes
 * @Date: 2024/10/9 19:53
 */
@UtilityClass
public class DateUtil {

    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    public static final String YYYY_MM_DD_NO_LINE = "yyyyMMdd";

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static Date dateTime(final String format, final String ts) throws ParseException {
        return new SimpleDateFormat(format).parse(ts);
    }

    /**
     * 获取当前时间所在星期的第一个星期
     * @param start 指定星期开始时间
     * @return
     */
    public static Date getStartTimeByWeek(DayOfWeek start) {
        LocalDate date = LocalDate.now();
        // 定义星期的开始是哪一天,计算星期的开始日期
        LocalDate startOfWeekDate = date.with(TemporalAdjusters.previousOrSame(start));
        // 将 LocalDate 转换为 ZonedDateTime（假设使用系统默认时区）
        ZonedDateTime zonedDateTime = startOfWeekDate.atStartOfDay(ZoneId.systemDefault());
        // 将 ZonedDateTime 转换为 Instant
        Instant instant = zonedDateTime.toInstant();
        // 将 Instant 转换为 Date
        return Date.from(instant);
    }

    /**
     * 今日0点
     *
     * @return
     */
    public static Date getDayStart() {
        return getDayStartTime(null);
    }

    /**
     * 获取指定时间0点
     *
     * @return
     */
    public static Date getDayStartTime(Date date) {
        Calendar cal = Calendar.getInstance();
        if (Objects.nonNull(date)) {
            cal.setTime(date);
        }
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取今天最后的时间点
     *
     * @param
     * @return
     */
    public static Date getLastTime() {
        return getDayLastTime(null);
    }

    /**
     * 获取指定时间最后的时间点
     *
     * @param endDate
     * @return
     */
    public static Date getDayLastTime(Date endDate) {
        Calendar c = Calendar.getInstance();
        if (Objects.nonNull(endDate)) {
            c.setTime(endDate);
        }
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        endDate = c.getTime();
        return endDate;
    }

    /**
     * 获取年龄
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getAge(Date startDate, Date endDate) {
        Period period = Period.between(startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
                endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        return period.getYears();
    }

    /**
     * 两个日期是否是一天
     *
     * @param first
     * @param second
     * @return
     */
    public static boolean isDay(Date first, Date second) {
        if (Objects.isNull(first) || Objects.isNull(second)) {
            return false;
        }
        return parseDateToStr(YYYY_MM_DD_NO_LINE, first).equals(parseDateToStr(YYYY_MM_DD_NO_LINE, second));
    }


}
